from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp import template
from google.appengine.ext import db

#please update this list if change tables, reset.py and unitTests.py depend on it
names = [
        'Season', 
        'Semester', 
        'Major', 
        'Time', 
        'AppState', 
        'Course', 
        'Instructor', 
        'Specialization', 
        'Language', 
        'Ta', 
        'Section', 
        'InstructorPref', 
        'TaSection',
        'TaTaHistory', 
        'TaQualification', 
        'TaSpecialization', 
        'TaLanguage', 
        'WantedTaInstructorPref', 
        'UnwantedTaInstructorPref',
        ]

class Season(db.Model):
    name = db.StringProperty(required = True)
    # =============== implicit members =============
    # semesters - list of Semesters for this season

class Semester(db.Model):
    season = db.ReferenceProperty(Season, collection_name = "semesters", required = True)
    year = db.IntegerProperty(required = True)
    # =============== implicit members =============
    # sections - list of Sections for this Semester
    # tas - list of Tas for this Semester
    def __str__(self):
        return str(self.season.name) + " " + str(self.year)

class Major(db.Model):
    name = db.StringProperty(required = True)
    # =============== implicit members =============
    # tas - list of Tas for this major

class Time(db.Model):
    'Models 4 different times of application'
    name = db.StringProperty(required = True)
    
class AppState(db.Model):
    semester = db.ReferenceProperty(Semester, collection_name = "appStates", required = True)
    time = db.ReferenceProperty(Time, collection_name = "appStates", required = True)

class Course(db.Model):
    identifier = db.StringProperty(required = True) #eg - cs373
    name = db.StringProperty(required = True) #eg - software engineering
    # =============== implicit members =============
    # sections - list of Sections for this Course
    # taQualifications - list of TaQualification associations for this Course
    
class Instructor(db.Model):
    firstName = db.StringProperty(required = True)
    lastName = db.StringProperty(required = True)
    eid = db.StringProperty(required = True)
    
class Specialization(db.Model):
    name = db.StringProperty(required = True)
    # =============== implicit members =============
    # taSpecializations - list of TaSpecialization associations for this Specialization
    # instructorPrefs - list of InstructorPrefs for this Specialization
    
class Language(db.Model):
    name = db.StringProperty(required = True)
    # =============== implicit members =============
    # taLanguages - list of TaLanguage associations for this Language

class Ta(db.Model):
    firstName = db.StringProperty(required = True)
    lastName = db.StringProperty(required = True)
    phone = db.StringProperty(required = False)
    email = db.StringProperty(required = False)
    major = db.ReferenceProperty(Major, required = False, collection_name = "tas")
    admissionDate = db.DateProperty(required = False)
    degree = db.StringProperty(required = False)
    supervisor = db.StringProperty(required = False)
    residency = db.BooleanProperty(required = False)
    nativeEnglish = db.BooleanProperty(required = False)
    semester = db.ReferenceProperty(Semester, collection_name = "tas", required = True)
    eid = db.StringProperty(required = False)
    submitted = db.BooleanProperty(required = True, default=False)
    # =============== implicit members =============
    # taSections - list of SectionTa associations for this Ta
    # taQaulifications - list of TaQualification  associations for this Ta
    # taSpecializations - list of TaSpecialization associations for this Ta
    # taLanguages - list of TaLanguage associations for this Ta
    # taTaHistory - list of TaHistory for this Ta
    # unwantedTaInstructorPrefs - list of UnwantedTaInstructorPref associations for this Ta
    # wantedTaInstructorPrefs - list of WantedTaInstructorPref associations for this Ta

class Section(db.Model):
    'Models an instance of a course for a given semester.'
    uniqueNumber = db.IntegerProperty(required = True)
    course = db.ReferenceProperty(Course, collection_name = "sections", required = True)
    instructor = db.ReferenceProperty(Instructor, collection_name = "sections", required = True)
    numTas = db.IntegerProperty(required = True)
    numStudents = db.IntegerProperty(required = True)
    semester = db.ReferenceProperty(Semester, collection_name = "sections",required = True)
    # =============== implicit members =============
    # taSections - list of TaSection associations for this Section
    # instructorPrefs - list of instructorPrefs for this section
    
class InstructorPref(db.Model):
    'Models preferences for given section'
    section = db.ReferenceProperty(Section, collection_name = 'instructorPrefs')
    nativeEnglish = db.BooleanProperty()
    specialization = db.ReferenceProperty(Specialization, collection_name = 'instructorPrefs')
    # =============== implicit members =============
    # unwantedTaInstructorPrefs - list of UnwantedTaInstructorPref associations for this Instructor
    # wantedTaInstructorPrefs - list of WantedTaInstructorPref associations for this Instructor
    
class TaSection(db.Model):
    'Models many-to-many Ta/Section association'
    section = db.ReferenceProperty(Section, collection_name = "taSections", required=True)
    ta = db.ReferenceProperty(Ta, collection_name = "taSections", required=True)
    
class TaQualification(db.Model):
    'Models many-to-many Ta/Qualification association'
    qualification = db.ReferenceProperty(Course, collection_name = "taQualifications", required=True)
    ta = db.ReferenceProperty(Ta, collection_name = "taQualifications", required=True)
    
class TaSpecialization(db.Model):
    'Models many-to-many Ta/Specialization association'
    specialization = db.ReferenceProperty(Specialization, collection_name = "taSpecializations", required=True)
    ta = db.ReferenceProperty(Ta, collection_name = "taSpecializations", required=True)

class TaLanguage(db.Model):
    'Models many-to-many Ta/Language association'
    language = db.ReferenceProperty(Language, collection_name = "taLanguages", required=True)
    ta = db.ReferenceProperty(Ta, collection_name = "taLanguages", required=True)

class TaTaHistory(db.Model):
    'Models many-to-many Ta/TaHistory association'
    taHistory = db.ReferenceProperty(Course, collection_name = "taTaHistory", required=True)
    ta = db.ReferenceProperty(Ta, collection_name = "taTaHistory", required=True)
    
class WantedTaInstructorPref(db.Model):
    'Models many-to-many Ta/InstructorPref association'
    instructorPref = db.ReferenceProperty(InstructorPref, collection_name = "wantedTaInstructorPrefs", required=True)
    ta = db.ReferenceProperty(Ta, collection_name = "wantedTaInstructorPrefs", required=True)
    
class UnwantedTaInstructorPref(db.Model):
    'Models many-to-many Ta/InstructorPref association'
    instructorPref = db.ReferenceProperty(InstructorPref, collection_name = "unwantedTaInstructorPrefs", required=True)
    ta = db.ReferenceProperty(Ta, collection_name = "unwantedTaInstructorPrefs", required=True)
